package com.hyh.pay.service.impl;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.hyh.feign.clients.CartClient;
import com.hyh.feign.clients.OrderClient;
import com.hyh.feign.domain.Cart;
import com.hyh.feign.domain.Orders;
import com.hyh.pay.constants.PayConstants;
import com.hyh.pay.dao.PayMapper;
import com.hyh.pay.domain.PayRecord;
import com.hyh.pay.domain.RequestParameter;
import com.hyh.pay.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Objects;


@Slf4j
@Service
public class PayServiceImpl implements PayService {

    /**
     * 获取配置文件里面的值
     * @param
     * @return
     **/
    @Value("${alipay.app-id}")
    private String appId;

    @Value("${alipay.pid}")
    private String pid;

    @Value("${alipay.private-key}")
    private String privateKey;

    @Value("${alipay.public-key}")
    private String publicKey;

    @Value("${alipay.gateway-url}")
    private String gatewayUrl;

    @Value("${alipay.sign-type}")
    private String signType;

    @Value("${alipay.charset}")
    private String charset;

    @Value("${alipay.alipay-public-key}")
    private String alipayPublicKey;

    @Value("${alipay.notify-url}")
    private String notifyUrl;

    @Value("${alipay.return-url}")
    private String returnUrl;

    private final String format = "json";

    @Autowired
    private CartClient cartClient;

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private PayMapper payMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public String pay(String orderNumber) throws AlipayApiException {
        RequestParameter requestParameter = new RequestParameter();
        if(Objects.nonNull(orderNumber)){
            Orders orderById = orderClient.getOrderById(Long.valueOf(orderNumber));
            if (orderById.getOrderStatus().equals("0")){
                return getString(requestParameter, orderById);
            }
        }
        return  "订单已支付";
    }


    //生成支付请求参数
    private String getString(RequestParameter requestParameter, Orders order) {
        // 生成支付请求参数
        requestParameter.setOut_trade_no(String.valueOf(order.getOrderNumber()));
        requestParameter.setSubject(order.getProductName());
        requestParameter.setTotal_amount(String.valueOf(order.getProductPrice()));
        requestParameter.setBody(order.getProductName());
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, format,
                                                            charset, publicKey, signType);
        //PC网页支付使用AlipayTradePagePayRequest传参，下面调用的是pageExecute方法
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setNotifyUrl(notifyUrl);
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setBizContent(JSON.toJSONString(requestParameter));
        // 调用SDK生成表单
        String result = null;
        try {
            result = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        return result;
    }


    // 支付成功的回调函数
    @Override
    public String payNotify(HttpServletRequest request) {
        // 获取订单号
        String out_trade_no = request.getParameter("out_trade_no");
        String tradeNo = request.getParameter("trade_no");
        // 根据订单号查询订单
        Orders order = orderClient.getOrderById(Long.valueOf(out_trade_no));
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")){
           orderClient.updateOrder(order.getId());
           // 将支付信息存入到数据库
            PayRecord payRecord = new PayRecord();
            payRecord.setPayTime(new Timestamp(System.currentTimeMillis() +  8 * 60 * 60 * 1000));
            payRecord.setUserId(order.getUserId());
            payRecord.setPayAmount(order.getProductPrice());
            payRecord.setPayStatus("已支付");
            payRecord.setOrderId(order.getId());
            payMapper.insert(payRecord);
            // 将支付订单号存储到redis当中
            stringRedisTemplate.opsForValue().set("trade:"+out_trade_no,tradeNo);

            // 发送消息到MQ 通知仓储服务
            rabbitTemplate.convertAndSend(PayConstants.PAY_EXCHANGE,
                    PayConstants.PAY_ROUTING_KEY,Long.valueOf(out_trade_no));

            // 发送消息到MQ 通知短信服务
            // 从redis当中取出number
            String number = stringRedisTemplate.opsForValue().get("login:number");
            if(number != null){
                rabbitTemplate.convertAndSend(PayConstants.PAY_EXCHANGE_NUMBER,
                        PayConstants.PAY_ROUTING_KEY_NUMBER,number);
            }
    }
        return "success";
    }

    // 退款
    @Override
    public String refund(String orderNumber) {
        AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,appId,
                privateKey,format,charset,
                alipayPublicKey,signType);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        Orders orders = orderClient.getOrderById(Long.valueOf(orderNumber));

        bizContent.put("trade_no", stringRedisTemplate.opsForValue().get("trade:"+orderNumber));
        bizContent.put("refund_amount",orders.getProductPrice());
        bizContent.put("out_request_no", RandomUtil.randomString(8));


        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            return "退款失败";
        }
        return response.getBody();
    }
}
